﻿using CoreShop.Library;
using CoreShop.Library.Units;
using CoreShop.Model;
using CoreShop.Model.FromBody;
using CoreShop.Model.UI;
using CoreShop.Services;
using Newtonsoft.Json;
using Sunny.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static CoreShop.Library.GlobalEnumVars;

namespace CoreShop.App.Payment.SxfPay
{
    public class SxfPay
    {
        //private string mno = "399200819168726";
        private corecmssystemsetup systemsetup = new corecmssystemsetup();
        private corecmspayaccount payaccount = new corecmspayaccount();
        public string privateKeyPem = @"MIIEowIBAAKCAQEA07/X9C5fQns5lW57VXxaClY3XBK2b2SX2JB9H54EqKV7ppyHyh0IDdBYBrGHkPdCUUbcPq0mFBWS7/2JI+BN11cD2kiZbIgIyEKaG4mgt/ownoSzkG7GZMjuvIYTAg+Lq4VZper/NXpcw51lqqpzlikVvYS58+vANps7CvgVqbytgzd1N0qCRz+8y2NVzRa6+lm079xsp4GKWkVe1BQbljzOvuHlsUp8e4T4S8KlasCvjQEC9QcjZGFbbrTpIEuzEP5X5aIJo1XDCtZ+9mH5JW4Sj8OfFgVlPQ22MeoOEprhZ0ZObZND758eS3fPjYjVgBu9lt9pqTk0ndT3ukCucwIDAQABAoIBADiWajXdNqPjnm3qypb71mwwwjae4ZY/Qb0kT+vlJMWVA8hwyHEg9QgMB5oyU1JQYa6qyy0MxMJVSaFNFhs6VFMZ8/OftzCj4gTyl5CIZSUFfXy/ZeVRVT+V2wcSpX3FfcPmrSCD/pPiEWxNYeAMETut2xt8nt0qwYFWVp8F0XQ8dQvRSr+Vmhu66c6cgnMbFYMOIMc8O9jlRrcX+alug7ZUGtSHMNzxSzjHnBFheuElFVABZ37M34/Y6wQ+7nubzXy1E0Jl109/4cuHPGVOkUbT9VRvnTqTAQ7JYfE8XTnoziPFQ8NJ2w6fTIdH+FT1N0DHnAVVyz6Blq+OpIQ1m4ECgYEA/mmiBVggoDpzKvCOiwhPazMzmB7Ie4ld4Nsl6IZufjhWZPw7fGmUVo0XEXcVh24Oj80SU0Xk9VsMCpvpR9JxJjJFatEIRUuzu1CCCBtsCNJGfydBH3RYxLV/FQ/6j/MPjaUAbkMTFrlPnU9GW8wKiMTK5he6/vlFyrJ5UouUSGECgYEA1RIQ0wyO+lLi/7FnAPlCjVeZHt9URQCJz367lqx6iWNIH+gZIicGoFT/lyAEqx5YKkIKlSMKO2o8dFNOypMEQDYuebtVey4Li40tjiWNGRXkTn+er08dYxVOIQzpdrkb1DQeLtrulmNiQU43PwErzIqv/GezEaqHyXBDs6P8l1MCgYEAg1urKjM8dT54pF0cXDDoQKNpKkwKm65raGP+iLaQal9QTEfntu8UhjPHC19/IDP1FM5/fbuC4iQmbXve0RSZE221ZdeT+6OAo2CIIwN1noBjodd0ynbaNoa3nPppFtYa27msJUJAouT/dGuwGkmZztA9Ktxp0qiGHohUGAi1gUECgYBq7igXYsQWiKZ3YBarfGyT9pRX1Ai8oGqJAbcvBNxyOqslqBuE8kT3DfE/bMgrAI2Kl54r/mvSKZyxXGW8cE+/0fE9EnDx4sfUf0OPhPTs0/nCE3YV0QSUh0qwd4RrGrcGpilHpoP6YWIcGB7Ntc6/VhK//2L0yLpgs8CmVPQdFQKBgCCUiOqszYgLNbI1IqPJ//NMyGFn1M2ZJhOcR1VYCJvI7YzheWF2ItnyEdKUD3N8QRBEN4vSKuj8IcMEwNpYSuErVBG0/LPIXMb7+/FVtGv6coaFCPnjsAsh5bC1Vff4PagJfk9/Inb6viybzM+Z5PR3j8c3jj7olvE+0Rd5wNRr";
        public SxfPay(corecmssystemsetup _systemsetup, corecmspayaccount _payaccount)
        {
            systemsetup = _systemsetup;
            payaccount = _payaccount;
        }

        //聚合支付参数设置
        private Hashtable GetPayParam(string sbillno, string authCode, decimal dAmount)
        {            
            Random random = new Random();
            Hashtable ht = new Hashtable();
            //tradeno = random.Next(9) + random.Next(9) + "20201019" + random.Next(9) + random.Next(9) + random.Next(9);
            //聚合支付参数
            DateTime mSysDate = DateTime.Now;
            //string sbillno = mSysDate.ToString("yyyyMMdd") + SysFunction.GetTimeStamp();
            GetHardwareInfo Ghd = new GetHardwareInfo();
            string sIPAddress = Ghd.GetIPAddress();
            ht.Add("ordNo", sbillno);
            ht.Add("mno", systemsetup.sxfMno);
            if (!string.IsNullOrEmpty(systemsetup.sxfDeviceNo))
                ht.Add("deviceNo", systemsetup.sxfDeviceNo);
            ht.Add("authCode", authCode);
            ht.Add("amt", dAmount);
            //ht.Add("payType", "WECHAT");
            //ht.Add("payWay", "03");
            ht.Add("subject", "商品");
            ht.Add("tradeSource", "01");
            ht.Add("trmIp", sIPAddress);
            if (!string.IsNullOrEmpty(systemsetup.sxfStoreNum))
                ht.Add("storeNum", systemsetup.sxfStoreNum); 
             
            return ht;
        }

        //聚合支付参数设置
        private Hashtable GetRefundParam(string ordNo,string origOrderNo, decimal dAmount)
        {
            Random random = new Random();
            Hashtable ht = new Hashtable();
            DateTime mSysDate = DateTime.Now;
            GetHardwareInfo Ghd = new GetHardwareInfo();
            string sIPAddress = Ghd.GetIPAddress();
            ht.Add("ordNo", ordNo);
            ht.Add("origOrderNo", origOrderNo);
            ht.Add("mno", systemsetup.sxfMno);
            if (!string.IsNullOrEmpty(systemsetup.sxfDeviceNo))
                ht.Add("deviceNo", systemsetup.sxfDeviceNo);
            ht.Add("amt", dAmount);
            return ht;
        }

        private string fillFullRequestMessage(string queryResult, ApiRequestBean requestMsgBody)
        {
            ApiRequestBeanNew data = new ApiRequestBeanNew();
            data.reqData = requestMsgBody.reqData;
            data.signType = requestMsgBody.signType;
            data.version = requestMsgBody.version;
            data.orgId = requestMsgBody.orgId;
            data.reqId = requestMsgBody.reqId;
            data.timestamp = requestMsgBody.timestamp;
            data.sign = queryResult;

            string result = Newtonsoft.Json.JsonConvert.SerializeObject(data);
            return result;
        }

        private string getPayMessage(Hashtable ht)
        {
            try
            {
                ApiRequestBean ApiRequestBean = new ApiRequestBean();
                ApiRequestBean.orgId = payaccount.orgId;  //机构号
                ApiRequestBean.reqId = Guid.NewGuid().ToString().Replace("-", "");
                ApiRequestBean.signType = "RSA";
                ApiRequestBean.timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                ApiRequestBean.version = "1.0";
                ApiRequestBean.reqData = ht;

                string rsaResult;
                string result = PackReflectionEntity<ApiRequestBean>.GetEntityToString(ApiRequestBean);
                //签名                
                rsaResult = RSAUtil.RSASign(result, payaccount.sign);
                //实体付签名传给接口
                string requestMessage = this.fillFullRequestMessage(rsaResult, ApiRequestBean);
                return requestMessage;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        //聚合支付参数设置
        private Hashtable GetQueryParam(string ordNo)
        {
            Random random = new Random();
            Hashtable ht = new Hashtable();
            ht.Add("mno", systemsetup.sxfMno);
            ht.Add("ordNo", ordNo);
            return ht;
        }

        public SxfQueryDataModel tradeQuery(string ordNo)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetQueryParam(ordNo);

            SxfQueryDataModel sxfQueryModel = new SxfQueryDataModel();

            string requestMessage = getPayMessage(ht);
            string responseJson = null;
            try
            {
                responseJson = RequestClient.Post("https://openapi.tianquetech.com/query/tradeQuery", requestMessage);               
                                
                SxfTradeQueryResult queryResult = JsonConvert.DeserializeObject<SxfTradeQueryResult>(responseJson);
                if ((queryResult != null) && (queryResult.code == "0000"))
                {
                    sxfQueryModel.queryResult = queryResult;
                    sxfQueryModel.msg = queryResult.respData.bizMsg;
                    switch (queryResult.respData.tranSts)
                    {
                        case "SUCCESS"://交易成功
                            sxfQueryModel.isSuccess = true;
                            return sxfQueryModel;                       
                        case "PAYING"://支付中
                            System.Threading.Thread.Sleep(1000);
                            sxfQueryModel.isPaying = true;
                            sxfQueryModel.msg = "支付中";
                            return sxfQueryModel;
                        case "FAIL"://交易失败
                        case "NOTPAY"://未支付
                        case "CLOSED"://已关闭
                        case "CANCELED"://已撤销
                            return sxfQueryModel;
                        default:
                            return sxfQueryModel;
                    }
                }                
                return sxfQueryModel;
            }
            catch (Exception ex)
            {
                sxfQueryModel.msg = ex.Message;
                return sxfQueryModel;
            }
        }
                
        public async Task<SxfQueryDataModel> tradeQueryAsync(string ordNo)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetQueryParam(ordNo);

            SxfQueryDataModel sxfQueryModel = new SxfQueryDataModel();

            string requestMessage = getPayMessage(ht);
            string responseJson = null;
            try
            {                
                responseJson = await HttpHelperAsync.PostAsync("https://openapi.tianquetech.com/query/tradeQuery", requestMessage);

                SxfTradeQueryResult queryResult = JsonConvert.DeserializeObject<SxfTradeQueryResult>(responseJson);
                if ((queryResult != null) && (queryResult.code == "0000"))
                {
                    sxfQueryModel.queryResult = queryResult;
                    sxfQueryModel.msg = queryResult.respData.bizMsg;
                    switch (queryResult.respData.tranSts)
                    {
                        case "SUCCESS"://交易成功
                            sxfQueryModel.isSuccess = true;
                            return sxfQueryModel;
                        case "PAYING"://支付中
                            System.Threading.Thread.Sleep(1000);
                            sxfQueryModel.isPaying = true;
                            sxfQueryModel.msg = "支付中";
                            return sxfQueryModel;
                        case "FAIL"://交易失败
                        case "NOTPAY"://未支付
                        case "CLOSED"://已关闭
                        case "CANCELED"://已撤销
                            return sxfQueryModel;
                        default:
                            return sxfQueryModel;
                    }
                }
                else
                {
                   if (queryResult != null) sxfQueryModel.msg = queryResult.msg;
                }
                return sxfQueryModel;
            }
            catch (Exception ex)
            {
                sxfQueryModel.msg = ex.Message;
                return sxfQueryModel;
            }
        }


        public bool SetCancel(string ordNo, ref string msg, ref string sTranSts)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetQueryParam(ordNo);

            string requestMessage = getPayMessage(ht);
            string responseJson = null;
            try
            {
                responseJson = RequestClient.Post("https://openapi.tianquetech.com/query/cancel", requestMessage);
                IDictionary<string, object> respData = null;
                respData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(responseJson);
                if (respData["code"].ToString() == "0000")
                {
                    string signResult = respData["respData"].ToString();
                    Hashtable row = (Hashtable)PluSoft.Utils.JSON.Decode(signResult);
                    sTranSts = CommFunc.ConvertToString(row["tranSts"]);
                    msg = CommFunc.ConvertToString(row["bizMsg"]);
                    switch (sTranSts)
                    {
                        case "SUCCESS"://交易成功
                            return true;
                        case "FAIL"://交易失败
                            msg = "支付失败";
                            return false;
                        case "NOTPAY"://未支付
                        case "CLOSED"://已关闭
                        case "CANCELED"://已撤销
                            msg = "支付中";
                            return true;
                    }
                }
                //SysFunction.WriteWxPayLogEx(requestMessage, "查询支付无效返回值", 0);
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public async Task<SxfPayResultModel> SetPayment(string ordNo, string authCode, decimal dAmount)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetPayParam(ordNo, authCode, dAmount);
            string requestMessage = getPayMessage(ht);
            await new corecmsprinttasklogServices().InsertAsync("支付请求：" + requestMessage);
            try
            {
                var responseJson = RequestClient.Post("https://openapi.tianquetech.com/order/reverseScan", requestMessage);
                await new corecmsprinttasklogServices().InsertAsync("支付返回：" + responseJson);
                SxfPayResultModel sxfPayResultModel = JsonConvert.DeserializeObject<SxfPayResultModel>(responseJson);
                return sxfPayResultModel;                
            }
            catch (Exception ex)
            {
                //payResult.msg = ex.Message;
                SxfPayResultModel sxfPayResultModelErr = new SxfPayResultModel();
                sxfPayResultModelErr.msg = ex.Message.Replace("openapi.tianquetech.com","移动支付远程服务器");
                return sxfPayResultModelErr;
            }
        }
                
        /// <summary>
        /// 退款申请
        /// </summary>
        /// <param name="ordNo"></param>
        /// <param name="authCode"></param>
        /// <param name="dAmount"></param>
        /// <param name="retCode"></param>
        /// <param name="msg"></param>
        /// <param name="TransactionID"></param>
        /// <returns></returns>
        public bool SetRefund(string ordNo,string origOrderNo, decimal dAmount, ref string msg)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetRefundParam(ordNo, origOrderNo, dAmount);

            string requestMessage = getPayMessage(ht);
            new corecmsprinttasklogServices().Insert("退款请求："+ requestMessage);
            string responseJson = null;
            try
            {
                responseJson = RequestClient.Post("https://openapi.tianquetech.com/order/refund", requestMessage);
                new corecmsprinttasklogServices().Insert("退款返回：" + responseJson);
                //IDictionary<string, object> respData = null;
                try
                {
                    SxfPayResultModel sxfPayResultModel = JsonConvert.DeserializeObject<SxfPayResultModel>(responseJson);
                    if ((sxfPayResultModel != null) && (sxfPayResultModel.code == "0000"))
                    {
                        msg = sxfPayResultModel.respData.bizMsg;
                        if (sxfPayResultModel.respData.tranSts == "REFUNDSUC")                   
                            return true;
                        else 
                        if (sxfPayResultModel.respData.tranSts == "REFUNDFAIL")
                            return false;
                        else
                            return refundQuery(ordNo, ref msg); 
                    }
                    return false;
                }
                catch (Exception ex)
                {
                    msg = ex.Message;
                    return false;
                }
            }
            catch (Exception ex)
            {
                msg = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 退款查询
        /// </summary>
        /// <param name="ordNo"></param>
        /// <param name="msg"></param>
        /// <param name="TransactionID"></param>
        /// <param name="sTranSts"></param>
        /// <returns></returns>
        public bool refundQuery(string ordNo, ref string msg)
        {
            Dictionary<string, object> Result = new Dictionary<string, object>();
            Hashtable ht = new Hashtable(); //创建一个Hashtable实例
            ht = GetQueryParam(ordNo);

            string requestMessage = getPayMessage(ht);
            string responseJson = null;
            int mTimes = 0;
            try
            {
            WaitingStart:
                {
                    responseJson = RequestClient.Post("https://openapi.tianquetech.com/query/refundQuery", requestMessage);
                    SxfPayResultModel sxfPayResultModel = JsonConvert.DeserializeObject<SxfPayResultModel>(responseJson);
                    if ((sxfPayResultModel != null) && (sxfPayResultModel.code == "0000"))
                    {
                        msg = sxfPayResultModel.respData.bizMsg;
                        switch (sxfPayResultModel.respData.tranSts)
                        {
                            case "REFUNDSUC"://退款成功
                                return true;
                            case "REFUNDFAIL"://交易失败
                                return false;
                            case "REFUNDING"://退款中
                                mTimes += 1;
                                System.Threading.Thread.Sleep(1000);
                                if (mTimes < 60) goto WaitingStart;
                                break;
                        }
                    }
                    //IDictionary<string, object> respData = null;
                    //respData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(responseJson);
                    //if (respData["code"].ToString() == "0000")
                    //{
                    //    string signResult = respData["respData"].ToString();
                    //    Hashtable row = (Hashtable)PluSoft.Utils.JSON.Decode(signResult);
                    //    string sTranSts = CommFunc.ConvertToString(row["tranSts"]);
                    //    msg = CommFunc.ConvertToString(row["bizMsg"]);
                    //    switch (sTranSts)
                    //    {
                    //        case "REFUNDSUC"://退款成功
                    //            return true;
                    //        case "REFUNDFAIL"://交易失败
                    //            return false;
                    //        case "REFUNDING"://退款中
                    //            mTimes += 1;
                    //            System.Threading.Thread.Sleep(1000);
                    //            if (mTimes < 60) goto WaitingStart;
                    //            break;
                    //    }
                    //}
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

    }
}
